using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using UtilZ.Dotnet.Ex.DebugViews;
using UtilZ.Dotnet.Ex.ZLog;

namespace UtilZ.Dotnet.Ex.Model
{
#pragma warning disable 8500
    /// <summary>
    /// IQ值类型柔性数组
    /// </summary>
    /// <typeparam name="T">元素类型</typeparam>
    [DebuggerTypeProxy(typeof(IQSequenceDebugView<>))]
    [DebuggerDisplay("Length = {Length}")]
    unsafe public partial class IQValueTypeFlexibleArray<T> : IDisposable, IEnumerable<KeyValuePair<T, T>> where T : struct
    {
        private bool _disposed = false;
        private T _defaultValue = default(T);

        /// <summary>
        /// 构造函数初始化
        /// </summary>
        /// <param name="mode">工作模式</param>
        public IQValueTypeFlexibleArray(FlexibleArrayMode mode)
        {
            this._mode = mode;
        }

        /// <summary>
        /// 构造函数初始化,不可扩展
        /// </summary>
        /// <param name="iDataPtr">原始I路数据buffer</param>
        /// <param name="qDataPtr">原始Q路数据buffer</param>
        /// <param name="length">数据长度</param>
        public IQValueTypeFlexibleArray(T* iDataPtr, T* qDataPtr, int length)
            : this(FlexibleArrayMode.Referenced)
        {
            this._iDataPtr = iDataPtr;
            this._qDataPtr = qDataPtr;
            this._length = length;
        }

        /// <summary>
        /// 构造函数初始化,不可扩展
        /// </summary>
        /// <param name="iqData">原始IQ路数据</param>
        public IQValueTypeFlexibleArray(IQSpanZ<T> iqData)
            : this(FlexibleArrayMode.Referenced)
        {
            this._iDataPtr = iqData.IDataPtr;
            this._qDataPtr = iqData.QDataPtr;
            this._length = iqData.Length;
        }

        /// <summary>
        /// 构造函数初始化
        /// </summary>
        /// <param name="capcity">初始化容量</param>
        /// <param name="length">数据容量</param>
        public IQValueTypeFlexibleArray(int capcity, int length)
            : this(FlexibleArrayMode.Independent)
        {
            if (length > capcity)
            {
                throw new ArgumentOutOfRangeException(nameof(length), $"数据长度\"{length}\"不能大小容量\"{capcity}\"");
            }

            this.ReallocArray(length);
            this._length = length;
        }





        private readonly FlexibleArrayMode _mode;
        /// <summary>
        /// 获取当前实例模式
        /// </summary>
        public FlexibleArrayMode Mode
        {
            get { return this._mode; }
        }

        /// <summary>
        /// 判断当前数据源是否是当前数组维护的数据[true:当前数组维护的数据;false:引用的数据]
        /// </summary>
        /// <returns>true:当前数组维护的数据;false:引用的数据</returns>
        private bool IsIndependent()
        {
            return this._mode == FlexibleArrayMode.Independent;
        }

        /// <summary>
        /// 判断当前数据源是否是引用的数据[true:引用的数据;false:当前数组维护的数据]
        /// </summary>
        /// <returns>true:引用 的数据;false:当前数组维护的数据</returns>
        private bool IsReferenced()
        {
            return this._mode == FlexibleArrayMode.Referenced;
        }


        private T* _iDataPtr = null;
        private T* _qDataPtr = null;
        private int _capcity = 0;


        private int _length = 0;
        /// <summary>
        /// 有效数据长度
        /// </summary>
        public int Length
        {
            get
            {
                return this._length;
            }
        }



        /// <summary>
        /// 获取I路指定索引处的值
        /// </summary>
        /// <param name="index">索引</param>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T GetIData(int index)
        {
            if (index < 0 || index >= this._length)
            {
                throw new IndexOutOfRangeException($"索引值\"{index}\"超出了数组范围,数据长度\"{this._length}\"");
            }

            return ref this._iDataPtr[index];
        }

        /// <summary>
        /// 获取或设置I路指定索引处的值
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="value">要设置的值</param>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public void SetIData(int index, T value)
        {
            if (index < 0 || index >= this._length)
            {
                throw new IndexOutOfRangeException($"索引值\"{index}\"超出了数组范围,数据长度\"{this._length}\"");
            }

            *(this._iDataPtr + index) = value;
        }


        /// <summary>
        /// 获取I路指定索引处的值
        /// </summary>
        /// <param name="index">索引</param>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T GetQData(int index)
        {
            if (index < 0 || index >= this._length)
            {
                throw new IndexOutOfRangeException($"索引值\"{index}\"超出了数组范围,数据长度\"{this._length}\"");
            }

            return ref this._qDataPtr[index];
        }

        /// <summary>
        /// 获取或设置I路指定索引处的值
        /// </summary>
        /// <param name="index">索引</param>
        /// <param name="value">要设置的值</param>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public void SetQData(int index, T value)
        {
            if (index < 0 || index >= this._length)
            {
                throw new IndexOutOfRangeException($"索引值\"{index}\"超出了数组范围,数据长度\"{this._length}\"");
            }

            *(this._qDataPtr + index) = value;
        }





        /// <summary>
        /// 获取第一个值,长度为0时抛出异常
        /// </summary>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T FirstI()
        {
            if (this._length == 0)
            {
                throw new ArgumentException("没有数据");
            }
            else
            {
                return ref this._iDataPtr[0];
            }
        }

        /// <summary>
        /// 获取第一个值或长度为0时取类型T的默念值
        /// </summary>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T FirstOrDefaultI()
        {
            if (this._length == 0)
            {
                return ref this._defaultValue;
            }
            else
            {
                return ref this._iDataPtr[0];
            }
        }

        /// <summary>
        /// 获取最后一个值,长度为0时抛出异常
        /// </summary>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T LastI()
        {
            if (this._length == 0)
            {
                throw new ArgumentException("没有数据");
            }
            else
            {
                return ref this._iDataPtr[this._length - 1];
            }
        }

        /// <summary>
        /// 获取最后一个值或长度为0时取类型T的默念值
        /// </summary>
        /// <returns>最后一个值或长度为0时取类型T的默念值</returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T LastOrDefaultI()
        {
            if (this._length == 0)
            {
                return ref this._defaultValue;
            }
            else
            {
                return ref this._iDataPtr[this._length - 1];
            }
        }



        /// <summary>
        /// 获取第一个值,长度为0时抛出异常
        /// </summary>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T FirstQ()
        {
            if (this._length == 0)
            {
                throw new ArgumentException("没有数据");
            }
            else
            {
                return ref this._qDataPtr[0];
            }
        }

        /// <summary>
        /// 获取第一个值或长度为0时取类型T的默念值
        /// </summary>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T FirstOrDefaultQ()
        {
            if (this._length == 0)
            {
                return ref this._defaultValue;
            }
            else
            {
                return ref this._qDataPtr[0];
            }
        }

        /// <summary>
        /// 获取最后一个值,长度为0时抛出异常
        /// </summary>
        /// <returns></returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T LastQ()
        {
            if (this._length == 0)
            {
                throw new ArgumentException("没有数据");
            }
            else
            {
                return ref this._qDataPtr[this._length - 1];
            }
        }

        /// <summary>
        /// 获取最后一个值或长度为0时取类型T的默念值
        /// </summary>
        /// <returns>最后一个值或长度为0时取类型T的默念值</returns>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public ref T LastOrDefaultQ()
        {
            if (this._length == 0)
            {
                return ref this._defaultValue;
            }
            else
            {
                return ref this._qDataPtr[this._length - 1];
            }
        }





        private int _count = 0;
        /// <summary>
        /// 获取或设置临时计数元素个数
        /// </summary>
        public int Count
        {
            get { return this._count; }
            set { this._count = value; }
        }

        /// <summary>
        /// 在现有Count值基础上加1
        /// </summary>
        /// <returns>旧值</returns>
        public int CountIncrement()
        {
            return Interlocked.Increment(ref this._count);
        }

        /// <summary>
        /// 在现有Count值基础上减1
        /// </summary>
        /// <returns>旧值</returns>
        public int CountDecrement()
        {
            return Interlocked.Decrement(ref this._count);
        }

        /// <summary>
        /// 在现有Count值基础上添加添加值
        /// </summary>
        /// <param name="value">添加值</param>
        /// <returns>旧值</returns>
        public int CountAdd(int value)
        {
            return Interlocked.Add(ref this._count, value);
        }

        /// <summary>
        /// 设置Count指定值
        /// </summary>
        /// <param name="value">目标值</param>
        /// <returns>旧值</returns>
        public int CountSet(int value)
        {
            return Interlocked.Exchange(ref this._count, value);
        }

        /// <summary>
        /// 获取或设置用户定义的数据
        /// </summary>
        public object Tag { get; set; }








        /// <summary>
        /// 检查容量是否足够,不够扩容,操作成功失败抛出异常
        /// </summary>
        /// <param name="length">需要的容量</param>
        public void Check(int length)
        {
            this.ReallocArray(length);
        }

        /// <summary>
        /// 检查容量是否足够,不够尝试扩容,操作成功返回true,失败返回false
        /// </summary>
        /// <param name="length">需要的容量</param>
        /// <returns>操作成功返回true,失败返回false</returns>
        public bool TryCheck(int length)
        {
            try
            {
                this.ReallocArray(length);
                return true;
            }
            catch (Exception ex)
            {
                ZLoger.Error(ex);
                return false;
            }
        }

        /// <summary>
        /// 检查容量是否足够,不够扩容.不调整或调整成功正常则设置数据长度为调整长度,操作成功失败抛出异常
        /// </summary>
        /// <param name="length">需要的元素个数</param>
        public void CheckSetLength(int length)
        {
            this.ReallocArray(length);
            this._length = length;
        }

        /// <summary>
        /// 检查容量是否足够,不够尝试扩容,操作成功返回true,失败返回false
        /// </summary>
        /// <param name="length">需要的元素个数</param>
        /// <returns>操作成功返回true,失败返回false</returns>
        public bool TryCheckSetLength(int length)
        {
            try
            {
                this.ReallocArray(length);
                this._length = length;
                return true;
            }
            catch (Exception ex)
            {
                ZLoger.Error(ex);
                return false;
            }
        }







        /// <summary>
        /// 获取当前数据长度的数据片
        /// </summary>
        /// <returns>数据片</returns>
        public IQSpanZ<T> GetIQSpanZ()
        {
            return new IQSpanZ<T>(this._iDataPtr, this._qDataPtr, this._length);
        }

        /// <summary>
        /// 获取指定数据长度的数据片
        /// </summary>
        /// <param name="count">指定数据长度</param>
        /// <returns></returns>
        public IQSpanZ<T> GetIQSpanZ(int count)
        {
            this.ReallocArray(count);
            return new IQSpanZ<T>(this._iDataPtr, this._qDataPtr, count);
        }

        /// <summary>
        /// 获取指定起始位置和数据长度的数据片
        /// </summary>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">指定数据长度</param>
        /// <returns></returns>
        public IQSpanZ<T> GetIQSpanZ(int startIndex, int count)
        {
            if (startIndex < 0 || count < 0)
            {
                throw new ArgumentOutOfRangeException($"参数值无效,startIndex:{startIndex},count:{count}");
            }

            this.ReallocArray(count);
            return new IQSpanZ<T>(this._iDataPtr + startIndex, this._qDataPtr + startIndex, count);
        }

        /// <summary>
        /// 获取当前数据长度的数据片
        /// </summary>
        /// <returns>数据片</returns>
        public Span<T> GetISpan()
        {
            return new Span<T>(this._iDataPtr, this._length);
        }

        /// <summary>
        /// 获取指定起始位置和数据长度的数据片
        /// </summary>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">指定数据长度</param>
        /// <returns></returns>
        public Span<T> GetISpan(int startIndex, int count)
        {
            if (startIndex < 0 || count < 0)
            {
                throw new ArgumentOutOfRangeException($"参数值无效,startIndex:{startIndex},count:{count}");
            }

            this.ReallocArray(startIndex + count);
            return new Span<T>(this._iDataPtr + startIndex, count);
        }

        /// <summary>
        /// 获取当前数据长度的数据片
        /// </summary>
        /// <returns>数据片</returns>
        public SpanZ<T> GetISpanZ()
        {
            return new SpanZ<T>(this._iDataPtr, this._length);
        }

        /// <summary>
        /// 获取指定起始位置和数据长度的数据片
        /// </summary>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">指定数据长度</param>
        /// <returns></returns>
        public SpanZ<T> GetISpanZ(int startIndex, int count)
        {
            if (startIndex < 0 || count < 0)
            {
                throw new ArgumentOutOfRangeException($"参数值无效,startIndex:{startIndex},count:{count}");
            }

            this.ReallocArray(startIndex + count);
            return new SpanZ<T>(this._iDataPtr + startIndex, count);
        }

        /// <summary>
        /// 获取当前数据长度的数据片
        /// </summary>
        /// <returns>数据片</returns>
        public Span<T> GetQSpan()
        {
            return new Span<T>(this._qDataPtr, this._length);
        }

        /// <summary>
        /// 获取当前数据长度的数据片
        /// </summary>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">指定数据长度</param>
        /// <returns>数据片</returns>
        public Span<T> GetQSpan(int startIndex, int count)
        {
            if (startIndex < 0 || count < 0)
            {
                throw new ArgumentOutOfRangeException($"参数值无效,startIndex:{startIndex},count:{count}");
            }

            this.ReallocArray(startIndex + count);

            return new Span<T>(this._qDataPtr + startIndex, count);
        }

        /// <summary>
        /// 获取当前数据长度的数据片
        /// </summary>
        /// <returns>数据片</returns>
        public SpanZ<T> GetQSpanZ()
        {
            return new SpanZ<T>(this._qDataPtr, this._length);
        }

        /// <summary>
        /// 获取当前数据长度的数据片
        /// </summary>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">指定数据长度</param>
        /// <returns>数据片</returns>
        public SpanZ<T> GetQSpanZ(int startIndex, int count)
        {
            if (startIndex < 0 || count < 0)
            {
                throw new ArgumentOutOfRangeException($"参数值无效,startIndex:{startIndex},count:{count}");
            }

            this.ReallocArray(startIndex + count);

            return new SpanZ<T>(this._qDataPtr + startIndex, count);
        }




        /// <summary>
        /// 创建一个I路数据流,外部需要释放流
        /// </summary>
        /// <param name="access">访问方式</param>
        /// <returns>数据流</returns>
        public Stream CreateIStream(FileAccess access)
        {
            long byteCount = this._length * sizeof(T);
            return new UnmanagedMemoryStream((byte*)this._iDataPtr, byteCount, byteCount, access);
        }

        /// <summary>
        /// 创建一个I路数据流,外部需要释放流
        /// </summary>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">需要的数据元素个数</param>
        /// <param name="access">访问方式</param>
        /// <returns>数据流</returns>
        public Stream CreateIStream(int startIndex, int count, FileAccess access)
        {
            if (startIndex < 0 || startIndex + count < 0)
            {
                throw new ArgumentOutOfRangeException($"参数值无效,startIndex:{startIndex},count:{count}");
            }

            if (startIndex + count > this._capcity)
            {
                this.ReallocArray(startIndex + count);
            }

            long byteCount = this._length * sizeof(T);
            return new UnmanagedMemoryStream((byte*)(this._iDataPtr + startIndex), byteCount, byteCount, access);
        }

        /// <summary>
        /// 创建一个Q路数据流,外部需要释放流
        /// </summary>
        /// <param name="access">访问方式</param>
        /// <returns>数据流</returns>
        public Stream CreateQStream(FileAccess access)
        {
            long byteCount = this._length * sizeof(T);
            return new UnmanagedMemoryStream((byte*)this._qDataPtr, byteCount, byteCount, access);
        }

        /// <summary>
        /// 创建一个Q路数据流,外部需要释放流
        /// </summary>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">需要的数据元素个数</param>
        /// <param name="access">访问方式</param>
        /// <returns>数据流</returns>
        public Stream CreateQStream(int startIndex, int count, FileAccess access)
        {
            if (startIndex < 0 || startIndex + count < 0)
            {
                throw new ArgumentOutOfRangeException($"参数值无效,startIndex:{startIndex},count:{count}");
            }

            if (startIndex + count > this._capcity)
            {
                this.ReallocArray(startIndex + count);
            }

            long byteCount = count * sizeof(T);
            return new UnmanagedMemoryStream((byte*)(this._qDataPtr + startIndex), byteCount, byteCount, access);
        }



        /// <summary>
        /// 用指定的值填充到当前对象数据指针指向的内容
        /// </summary>
        /// <param name="value">填充值</param>        
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public void Fill(T value)
        {
            if (this._length <= 0)
            {
                return;
            }

            new Span<T>(this._iDataPtr, this._length).Fill(value);
            new Span<T>(this._qDataPtr, this._length).Fill(value);
        }

        /// <summary>
        /// 用指定的值填充到当前对象数据指针指向的内容
        /// </summary>
        /// <param name="startIndex">起始位置</param>
        /// <param name="count">填充个数</param>
        /// <param name="value">填充值</param>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public void Fill(int startIndex, int count, T value)
        {
            if (this._length <= 0 || count == 0)
            {
                return;
            }

            if (startIndex < 0 ||
                count < 0 ||
                startIndex + count > this._length)
            {
                throw new ArgumentOutOfRangeException($"参数值无效,startIndex:{startIndex},count:{count}");
            }

            new Span<T>(this._iDataPtr + startIndex, this._length).Fill(value);
            new Span<T>(this._qDataPtr + startIndex, this._length).Fill(value);
        }



        /// <summary>
        /// 将I路数据拷贝到列表中
        /// </summary>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public List<T> ToListI()
        {
            if (this._length <= 0)
            {
                return new List<T>();
            }

            T* ptr = this._iDataPtr;
            var destination = new List<T>(this._length);
            for (int i = 0; i < this._length; i++)
            {
                destination.Add(*ptr++);
            }

            return destination;
        }

        /// <summary>
        /// 将Q路数据拷贝到列表中
        /// </summary>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public List<T> ToListQ()
        {
            if (this._length <= 0)
            {
                return new List<T>();
            }

            T* ptr = this._qDataPtr;
            var destination = new List<T>(this._length);
            for (int i = 0; i < this._length; i++)
            {
                destination.Add(*ptr++);
            }

            return destination;
        }




        /// <summary>
        /// 分片返回一个固定的柔性数组
        /// </summary>
        /// <param name="start">The index at which to begin this slice.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;Length).
        /// </exception>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public IQValueTypeFlexibleArray<T> Slice(int start)
        {
            if (start < 0 || start > this._length)
            {
                throw new ArgumentOutOfRangeException(nameof(start), $"start:{start},Length:{this._length}");
            }

            return new IQValueTypeFlexibleArray<T>(this._iDataPtr + start, this._qDataPtr + start, this._length - start);
        }

        /// <summary>
        /// 分片返回一个固定的柔性数组
        /// </summary>
        /// <param name="start">The index at which to begin this slice.</param>
        /// <param name="length">The desired length for the slice (exclusive).</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Thrown when the specified <paramref name="start"/> or end index is not in range (&lt;0 or &gt;Length).
        /// </exception>
#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        public IQValueTypeFlexibleArray<T> Slice(int start, int length)
        {
            if (start < 0 || start > this._length)
            {
                throw new ArgumentOutOfRangeException(nameof(start), $"start:{start},length:{length},Length:{this._length}");
            }

            if (start + length > this._length)
            {
                throw new ArgumentOutOfRangeException(nameof(length), $"start:{start},length:{length},Length:{this._length}");
            }

            return new IQValueTypeFlexibleArray<T>(this._iDataPtr + start, this._qDataPtr + start, length);
        }



        /// <summary>
        /// 引用数据
        /// </summary>
        /// <param name="iDataPtr">被引用数据的I路数据指针</param>
        /// <param name="qDataPtr">被引用数据的Q路数据指针</param>
        /// <param name="length">被引用数据的数据长度</param>
        public void Reference(T* iDataPtr, T* qDataPtr, int length)
        {
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException($"长度值\"{length}\"无效,超出范围,不能小于0");
            }

            if (this.IsIndependent())
            {
                throw new InvalidOperationException($"当前数组对象模式为内存独立模式,不支持引用其它对象的数据内存.");
            }

            this._iDataPtr = iDataPtr;
            this._qDataPtr = qDataPtr;
            this._length = length;
        }

        /// <summary>
        /// 引用数据
        /// </summary>
        /// <param name="data">被引用数据的数据</param>
        public void Reference(IQSpanZ<T> data)
        {
            if (data.Length <= 0)
            {
                return;
            }

            if (this.IsIndependent())
            {
                throw new InvalidOperationException($"当前数组对象模式为内存独立模式,不支持引用其它对象的数据内存.");
            }

            this._iDataPtr = data.IDataPtr;
            this._qDataPtr = data.QDataPtr;
            this._length = data.Length;
        }

        /// <summary>
        /// 引用数据
        /// </summary>
        /// <param name="arr">被引用数据的数组</param>
        public void Reference(IQValueTypeFlexibleArray<T> arr)
        {
            if (arr == null)
            {
                return;
            }

            if (this.IsIndependent())
            {
                throw new InvalidOperationException($"当前数组对象模式为内存独立模式,不支持引用其它对象的数据内存.");
            }

            this._iDataPtr = arr._iDataPtr;
            this._qDataPtr = arr._qDataPtr;
            this._length = arr._length;
            this._capcity = arr._capcity;
        }

        /// <summary>
        /// 引用数据
        /// </summary>
        /// <param name="arr">被引用数据的数组</param>
        /// <param name="startIndex">被引用数据的数据起始偏移位置</param>
        /// <param name="length">被引用数据的数据长度</param>
        public void Reference(IQValueTypeFlexibleArray<T> arr, int startIndex, int length)
        {
            if (arr == null)
            {
                return;
            }

            if (startIndex < 0)
            {
                throw new ArgumentOutOfRangeException($"数据起始偏移位置\"{startIndex}\"无效,超出范围,不能小于0");
            }

            if (startIndex + length < 0)
            {
                throw new ArgumentOutOfRangeException($"长度值\"{startIndex + length}\"无效,超出范围,不能小于0");
            }

            if (startIndex + length > arr._length)
            {
                throw new ArgumentOutOfRangeException($"起始索引{startIndex}加长度值\"{startIndex + length}\"无效,超出范围");
            }

            if (this.IsIndependent())
            {
                throw new InvalidOperationException($"当前数组对象模式为内存独立模式,不支持引用其它对象的数据内存.");
            }

            this._iDataPtr = arr._iDataPtr + startIndex;
            this._qDataPtr = arr._qDataPtr + startIndex;
            this._length = length;
            this._capcity = length;
        }





        /// <summary>
        /// 重写ToString
        /// </summary>
        /// <returns>String</returns>
        public override string ToString()
        {
            return this.GetIQSpanZ().ToString();
        }



        #region IEnumerable

        /// <summary>
        /// IEnumerable
        /// </summary>
        /// <returns></returns>
        public IEnumerator<KeyValuePair<T, T>> GetEnumerator()
        {
            return new IQValueTypeFlexibleArrayEnumerator(this);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        private class IQValueTypeFlexibleArrayEnumerator : IEnumerator<KeyValuePair<T, T>>
        {
            private readonly IQValueTypeFlexibleArray<T> _arr;
            private int _index = -1;
            public IQValueTypeFlexibleArrayEnumerator(IQValueTypeFlexibleArray<T> arr)
            {
                this._arr = arr;
            }

            public KeyValuePair<T, T> Current
            {
                get
                {
                    return new KeyValuePair<T, T>(this._arr._iDataPtr[this._index], this._arr._qDataPtr[this._index]);
                }
            }

            object IEnumerator.Current
            {
                get
                {
                    return this.Current;
                }
            }

            public void Dispose()
            {

            }

            public bool MoveNext()
            {
                this._index++;
                if (this._index < this._arr._length)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }

            public void Reset()
            {
                this._index = -1;
            }
        }

        #endregion

    }
}
